<?php
/**
 * 建造者模式
 *
 * 创建类模式
 * 构建复杂对象 ,
 *
 * 一个产品 , 如果他的构造很复杂 , 可以考虑通过 建造者模式来创建
 * 对象的创建不再依赖客户端 , 而是交给建造者 , 客户端依赖建造者 , 建造者可以灵活替换 即 依赖稳定
 * */
namespace builder;

use Cassandra\Cluster\Builder;

/**
 * 再看建造者模式
 *      将一个复杂对象的构建和他的表示分离 , 同样的构建过程可以创建不同的表示
 *
 *      为每一个复杂对象创建一个具体的建造者, 通过指挥者来控制建造者的建造顺序
 *      指挥者在这里存在的价值为 : 指定建造顺序 , 可能在建造的过程中有些过程需要单独处理 , 所以交给了指挥者来做
 * */
class Product{
    protected $name;
    protected $sex;
    protected $money;
    protected $desc;

    public function setMoney($money) {
        $this->money = $money;
    }

    /**
     * @param mixed $desc
     */
    public function setDesc($desc)
    {
        $this->desc = $desc;
    }

    /**
     * @param mixed $name
     */
    public function setName($name)
    {
        $this->name = $name;
    }

    /**
     * @param mixed $sex
     */
    public function setSex($sex)
    {
        $this->sex = $sex;
    }

    /**
     * @return mixed
     */
    public function getSex()
    {
        return $this->sex;
    }

    /**
     * @return mixed
     */
    public function getDesc()
    {
        return $this->desc;
    }

    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @return mixed
     */
    public function getMoney()
    {
        return $this->money;
    }

    public function hello(){
        echo $this->name.$this->sex.$this->money.$this->desc;
    }
}


/**
 * 给 product 构造的类, 关联一个product
 * */
class BuilderProduct{
    /**
     * @var Product $product
     * */
    protected $product;
    public function __construct()
    {
        $this->product = new Product();
    }
    public function getProduct(){
        return $this->product;
    }
    public function builderName($data){
        $this->product->setName('通过创建者创建:'.$data);
    }
    public function builderSex($data){
        $this->product->setSex('通过创建者创建:'.$data);
    }
    public function builderDesc($data){
        $this->product->setDesc('通过创建者创建:'.$data);
    }
    public function builderMoney($data){
        $this->product->setMoney('通过创建者创建:'.$data);
    }
}


class Director{
    /**
     * @var BuilderProduct
     * */
    protected $builder;
    public function __construct($builder)
    {
        $this->builder = $builder;
    }

    /**
     * @return Product
     * */
    public function builderProduct(){
        $this->builder->builderDesc(10);
        $this->builder->builderMoney(10);
        $this->builder->builderName(10);
        $this->builder->builderSex(10);

        return $this->builder->getProduct();
    }
}
// 真实环境下 通过读取配置 获取真实的构建者 , 然后注入到导演对象来完成创建
$product = (new Director(new BuilderProduct()))->builderProduct();
$product->hello();
